import type { FormInstance } from 'element-plus';

/**
 * 防抖函数
 * @param {function} fn 事件处理函数
 * @param {number} [delay=20] 延迟时间
 * @param {boolean} [isImmediate=false] 是否立刻执行
 * @param {object} [context=this] 上下文对象
 * @returns {Function} 事件处理函数
 */
export function debounce(fn: (...args: any[]) => void, delay = 20, isImmediate = false, context: any = undefined) {
	// 使用闭包，保存执行状态，控制函数调用顺序
	let timer: number | undefined = undefined;
	return function (...args: any[]) {
		if (timer !== undefined) clearTimeout(timer);
		const _fn = function () {
			timer = undefined;
			if (!isImmediate) fn.apply(context, args);
		};
		// 是否滚动时立刻执行
		const callNow = timer === undefined && isImmediate;
		timer = window.setTimeout(_fn, delay);
		if (callNow) fn.apply(context, args);
	};
}

const raFrame =
	window.requestAnimationFrame ||
	function (callback) {
		return window.setTimeout(callback, 1000 / 60);
	};

/**
 * 动画延时函数
 * @function
 * @param {function} callback 动画回调函数
 * @return {number} id
 */
export const requestAnimationFrame = raFrame;

/**
 * 清除动画延时
 * @function
 * @param {number} id
 */
export const cancelAnimationFrame =
	window.cancelAnimationFrame ||
	function (id: number) {
		window.clearTimeout(id);
	};

/**
 * 节流函数 isLocked在执行中时禁止后续相同函数执行
 * @param {function} fn 事件处理函数
 * @param {boolean} [isImmediate=false] 是否立刻执行
 * @param {object} [context=this] 上下文对象
 * @returns {Function} 事件处理函数
 */
export function throttle(fn: (...args: any[]) => void, isImmediate = false, context: any = undefined) {
	let isLocked: boolean;
	return function (...args: any[]) {
		if (isLocked) return;
		isLocked = true;
		raFrame(function () {
			isLocked = false;
			fn.apply(context, args);
		});
		isImmediate && fn.apply(context, args);
	};
}

/**
 * 回显数据字典（字符串数组）
 * @param {Array} datas 数组原始数据
 * @param {string | number | undefined} value 需要查找的值 多个时按照separator拼接
 * @param {string} separator 多个值时拼接的标识（默认为 , ）
 * @param {object} fileType 需要对应的 val和key
 * @returns
 */
type valueType = string | number | undefined;
export function selectDictLabel(
	datas: Record<string, string | number>[],
	value: valueType,
	separator = ',',
	{ dictValue = 'dictValue', dictLabel = 'dictLabel' } = {}
) {
	// 若datas为空或value为null、undefined，则直接返回空字符串
	if (!datas?.length || value == null) return '';

	if (typeof value === 'number') {
		return datas.find((item) => item[dictValue] == value)?.[dictLabel];
	}

	if (typeof value === 'string') {
		const actions: valueType[] = [],
			temp = String(value)?.split(separator);

		temp.forEach((item) => {
			const action = datas.find((dict) => dict[dictValue] == item);
			if (action) {
				actions.push(action[dictLabel]);
			}
		});

		return actions.join(',');
	}
}

/**
 * 表单重置
 * @param {object} formEl 表单实例  refName
 */

export function resetForm(refName: FormInstance | null) {
	// 如果传入的refName存在,则调用resetFields方法重置表单
	if (refName) {
		refName.resetFields?.();
		// const resetFields = (refName as FormInstance).resetFields || (refName as refNameType).$refs.refMyForm?.resetFields;
		// resetFields();
	}
}

/**
 * 生成随机GUID
 * @return {string}
 */
export function guid() {
	return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
		.replace(/[xy]/g, function (c) {
			const r = (Math.random() * 16) | 0,
				v = c === 'x' ? r : (r & 0x3) | 0x8;
			return v.toString(16);
		})
		.toUpperCase();
}

// transitionGroup切换定义参数函数
import { customRef } from 'vue';
export function transitionGroupRef(value: string | null | boolean, delay = 300) {
	return customRef((track, trigger) => ({
		get() {
			track();
			return value;
		},
		set(newValue) {
			value = null;
			trigger();
			setTimeout(() => {
				value = newValue;
				trigger();
			}, delay);
		}
	}));
}
